package cn.yunbamboos.mybatis.mapper;

import cn.yunbamboos.mybatis.Constants;
import cn.yunbamboos.mybatis.conditions.Conditions;
import cn.yunbamboos.mybatis.metadata.IPage;
import cn.yunbamboos.mybatis.toolkit.GenericUtils;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;

public interface GenericMapper<T> extends Mapper {

    /**
     * 查询表中所有记录
     * 注：小配置表使用
     *
     * @return 数据库行列表
     */
    List<T> queryAllList();

    /**
     * 新增数据记录
     *
     * @param t 新增数据行数
     */
    int insert(T t);

    /**
     * 更新数据记录
     *
     * @param t 更新数据行数
     */
    int update(T t);

    /**
     * 通过主键查询数据记录(单主键)
     *
     * @return 对应数据记录
     */
    Optional<T> queryByPrimaryKey(Serializable id);

    /**
     * 通过主键删除数据记录(单主键)
     *
     * @return 影响数据行数
     */
    int deleteByPrimaryKey(Serializable id);

    /**
     * 通过主键查询数据记录(多主键)
     *
     * @param ids 主键列表  按照配置顺序添加
     * @return 对应数据记录
     */
    default Optional<T> queryByPrimaryKeys(Serializable... ids) {
        return GenericUtils.createConditions(getClass(), ids).flatMap(this::queryByPrimaryKeys);
    }

    /**
     * 通过主键查询数据记录(多主键)
     *
     * @param conditions 主键列表
     * @return 对应数据记录
     */
    Optional<T> queryByPrimaryKeys(Conditions conditions);

    /**
     * 通过主键删除数据记录(多主键)
     *
     * @param ids 主键列表  按照配置顺序添加
     * @return 影响数据行数
     */
    default int deleteByPrimaryKeys(Serializable... ids) {
        return GenericUtils.createConditions(getClass(), ids).map(this::deleteByPrimaryKeys).orElse(0);
    }

    /**
     * 通过主键删除数据记录(多主键)
     *
     * @param conditions 主键列表
     * @return 影响数据行数
     */
    int deleteByPrimaryKeys(Conditions conditions);

    /**
     * 按照条件查询单条记录
     * */
    Optional<T> queryForObject(@Param(Constants.CONDITIONS) Conditions conditions);

    /**
     * 按照条件查询多条记录
     * */
    List<T> queryForList(@Param(Constants.CONDITIONS) Conditions conditions);
    /**
     * 分页统计总条数
     * */
    Integer countForPage(@Param(Constants.PAGE) IPage<T> page, @Param(Constants.CONDITIONS) Conditions conditions);
    /**
     * 查询分页数据
     * */
    List<T> queryForPage(@Param(Constants.PAGE) IPage<T> page, @Param(Constants.CONDITIONS) Conditions conditions);

}
